package main

import (
	"context"
	"crawler/conf"
	"crawler/datasource"
	duplicateRpc "crawler/grpc/duplicate-rpc"
	"fmt"
	"github.com/gomodule/redigo/redis"
	"google.golang.org/grpc"
	"log"
	"net"
)

type rpcUser struct{}

func (u *rpcUser) SendUsers(ctx context.Context,
	in *duplicateRpc.SendUserRequest) (*duplicateRpc.SendUserReply, error) {

	usersCh <- in.Users

	log.Println("调用sendUser")
	return &duplicateRpc.SendUserReply{
		Msg: "成功送达users到duplicate模块",
	}, nil
}

func (u *rpcUser) GetUser(ctx context.Context,
	in *duplicateRpc.GetUserRequest) (*duplicateRpc.GetUserReply, error) {

	userId := getUserId()

	// 获取到的userId可能为""，该如何处理交给get-article服务去判断
	log.Println("调用getUser")
	return &duplicateRpc.GetUserReply{
		User: userId,
	}, nil
}

func bootRpcServer() {
	listener, err := net.Listen("tcp", "0.0.0.0:28080")
	if err != nil {
		log.Fatal("modular.duplicate.bootRpcGetUser error=", err)
	}

	// 实例化gRPC server
	server := grpc.NewServer()
	// 注册server
	duplicateRpc.RegisterDuplicateServer(server, &rpcUser{})

	fmt.Println("Listen on: 0.0.0.0:28080")
	// 启动监听
	server.Serve(listener)
}

// 将解析好的是数据去重
func duplicate(users []string, conn redis.Conn) []string {
	res := []string{}
	for _, userId := range users {
		rep, err := conn.Do("SADD", conf.DuplicateKey, userId)
		if err != nil {
			log.Panicln("modular.get-article.Do error=", err)
			continue
		}
		v1 := rep.(int64)

		// 插入不成功
		if v1 == 0 {
			//fmt.Println(v1)
			// 插入不成功则跳过
			continue
		} else { // 插入成功
			res = append(res, userId)
		}
	}
	return res
}

// 去重好的数据插入去重队列
func queue(users []string, conn redis.Conn) {
	for _, user := range users {
		// 用管道的方式批量插入
		conn.Send("SADD", conf.QueueKey, user)
	}
	conn.Flush()
	//conn.Receive()
}

// 去重和插入排队队列
func worker(users []string, pool *redis.Pool) {
	conn := pool.Get()
	defer conn.Close()

	// 去重
	res := duplicate(users, conn)

	// 去重后的结果插入队列
	if len(res) > 1 {
		queue(res, conn)
	}
}

func getUserId() string {
	pool := datasource.InstanceCache()
	conn := pool.Get()
	defer conn.Close()

	rep := ""
	rep, err := redis.String(conn.Do("SPOP", conf.QueueKey))
	if err != nil {
		log.Println("modular.duplicate-worker.getUserId error=", err)
		return rep
	}
	return rep
}
